import pygame
import sys
import random
import math

# 初始化pygame
pygame.init()
pygame.font.init()

# 确保中文能正常显示
font = pygame.font.SysFont(['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC'], 36)
small_font = pygame.font.SysFont(['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC'], 24)

# 游戏窗口设置
WIDTH, HEIGHT = 600, 800
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("跳一跳")

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (200, 200, 200)
BLUE = (0, 0, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
YELLOW = (255, 255, 0)
COLORS = [BLUE, RED, GREEN, YELLOW]

# 游戏参数
FPS = 60
JUMP_POWER_INCREASE = 0.5  # 每帧跳跃力度增加量
GRAVITY = 0.8  # 重力加速度
PLATFORM_SPEED = 5  # 平台移动速度
MIN_PLATFORM_WIDTH = 80  # 最小平台宽度
MAX_PLATFORM_WIDTH = 150  # 最大平台宽度
PLATFORM_GAP = 200  # 平台垂直间距
SCORE_INCREASE = 10  # 每成功跳跃一次增加的分数


# 玩家类
class Player:
    def __init__(self):
        self.x = WIDTH // 2
        self.y = HEIGHT // 2
        self.radius = 30
        self.color = BLUE
        self.jump_power = 0
        self.jumping = False
        self.falling = False
        self.velocity_y = 0
        self.score = 0
        self.on_platform = False
        self.current_platform = None

    def draw(self, screen):
        # 绘制玩家
        pygame.draw.circle(screen, self.color, (self.x, self.y), self.radius)
        pygame.draw.circle(screen, WHITE, (self.x - 10, self.y - 10), 5)  # 眼睛

        # 如果正在蓄力，显示蓄力条
        if self.jumping:
            power_ratio = self.jump_power / 30
            power_bar_height = 100 * power_ratio
            pygame.draw.rect(screen, RED,
                             (self.x - 5, self.y - self.radius - 20 - power_bar_height, 10, power_bar_height))

    def update(self):
        if self.jumping:
            self.jump_power += JUMP_POWER_INCREASE
            if self.jump_power > 30:  # 最大蓄力
                self.jump_power = 30

        if self.falling:
            self.velocity_y += GRAVITY
            self.y += self.velocity_y

        # 检测是否掉出屏幕
        if self.y > HEIGHT + 100:
            return False

        return True

    def jump(self):
        if self.jumping:
            self.velocity_y = -self.jump_power * 2
            self.jumping = False
            self.falling = True
            self.jump_power = 0
            self.on_platform = False
            self.current_platform = None

    def start_jump(self):
        if not self.jumping and not self.falling:
            self.jumping = True

    def check_collision(self, platforms):
        if self.falling:
            for platform in platforms:
                if (self.x + self.radius > platform.x and
                        self.x - self.radius < platform.x + platform.width and
                        self.y + self.radius > platform.y and
                        self.y - self.radius < platform.y + platform.height):

                    # 从上方落下并接触平台顶部
                    if self.velocity_y > 0 and self.y + self.radius < platform.y + 20:
                        self.y = platform.y - self.radius
                        self.velocity_y = 0
                        self.falling = False
                        self.on_platform = True
                        self.current_platform = platform

                        # 增加分数
                        if platform not in platforms[:2]:  # 排除初始平台
                            self.score += SCORE_INCREASE

                        return True
        return False


# 平台类
class Platform:
    def __init__(self, x, y, width=None):
        self.x = x
        self.y = y
        self.width = width if width is not None else random.randint(MIN_PLATFORM_WIDTH, MAX_PLATFORM_WIDTH)
        self.height = 20
        self.color = random.choice(COLORS)
        self.moving = random.choice([True, False])
        self.direction = random.choice([-1, 1])  # -1向左，1向右

    def draw(self, screen):
        pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height))
        pygame.draw.rect(screen, BLACK, (self.x, self.y, self.width, self.height), 2)  # 边框

    def update(self):
        if self.moving:
            self.x += self.direction * PLATFORM_SPEED

            # 碰到边界反弹
            if self.x <= 0:
                self.x = 0
                self.direction = 1
            elif self.x + self.width >= WIDTH:
                self.x = WIDTH - self.width
                self.direction = -1


# 游戏类
class Game:
    def __init__(self):
        self.player = Player()
        self.platforms = []
        self.game_over = False
        self.high_score = 0
        self.setup_game()

    def setup_game(self):
        # 创建初始平台
        self.platforms = []
        # 底部平台
        self.platforms.append(Platform(WIDTH // 2 - 100, HEIGHT - 100, 200))
        # 上方平台
        for i in range(5):
            x = random.randint(0, WIDTH - MIN_PLATFORM_WIDTH)
            y = HEIGHT - 200 - i * PLATFORM_GAP
            self.platforms.append(Platform(x, y))

        # 放置玩家在第一个平台上
        self.player = Player()
        self.player.y = self.platforms[0].y - self.player.radius
        self.player.on_platform = True
        self.player.current_platform = self.platforms[0]
        self.game_over = False

    def update(self):
        if self.game_over:
            return

        # 更新玩家
        if not self.player.update():
            self.game_over = True
            if self.player.score > self.high_score:
                self.high_score = self.player.score

        # 检查碰撞
        self.player.check_collision(self.platforms)

        # 更新平台
        for platform in self.platforms:
            platform.update()

        # 滚动屏幕
        if self.player.y < HEIGHT // 3 and self.player.falling:
            scroll_amount = HEIGHT // 3 - self.player.y
            self.player.y = HEIGHT // 3

            # 移动所有平台
            for platform in self.platforms:
                platform.y += scroll_amount

            # 移除离开屏幕的平台并创建新平台
            while self.platforms[0].y > HEIGHT:
                self.platforms.pop(0)
                x = random.randint(0, WIDTH - MIN_PLATFORM_WIDTH)
                y = self.platforms[-1].y - PLATFORM_GAP
                self.platforms.append(Platform(x, y))

    def draw(self, screen):
        # 绘制背景
        screen.fill(GRAY)

        # 绘制平台
        for platform in self.platforms:
            platform.draw(screen)

        # 绘制玩家
        self.player.draw(screen)

        # 绘制分数
        score_text = small_font.render(f"分数: {self.player.score}", True, BLACK)
        screen.blit(score_text, (20, 20))

        # 绘制最高分
        high_score_text = small_font.render(f"最高分: {self.high_score}", True, BLACK)
        screen.blit(high_score_text, (20, 50))

        # 游戏结束界面
        if self.game_over:
            game_over_text = font.render("游戏结束", True, RED)
            restart_text = small_font.render("按空格键重新开始", True, BLACK)

            screen.blit(game_over_text, (WIDTH // 2 - game_over_text.get_width() // 2, HEIGHT // 3))
            screen.blit(restart_text, (WIDTH // 2 - restart_text.get_width() // 2, HEIGHT // 2))


# 主函数
def main():
    clock = pygame.time.Clock()
    game = Game()

    running = True
    while running:
        clock.tick(FPS)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    if game.game_over:
                        game.setup_game()
                    elif game.player.on_platform:
                        game.player.jump()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:  # 左键
                    if not game.game_over:
                        game.player.start_jump()
            elif event.type == pygame.MOUSEBUTTONUP:
                if event.button == 1:  # 左键
                    if not game.game_over:
                        game.player.jump()

        # 更新游戏
        game.update()

        # 绘制游戏
        game.draw(screen)

        # 更新显示
        pygame.display.flip()

    pygame.quit()
    sys.exit()


if __name__ == "__main__":
    main()